#include <cstdlib>
#include <stdio.h>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <unistd.h>
using namespace std;

//#define GetFaceInformation "nfdc face"
//#define KILLZombieFace "nfdc face destroy "
#define MAXSIZE 10240

string int2string(int number);
map<int,string> findAndKillZombieFaces();
string execLinuxCommand(const string& linux_command);
int getFaceID(string faceInfoString);
string getFaceOut(string faceInfoString);

map<int,string> faceInfoMap;

int main(){
  //string s=execLinuxCommand(GetFaceInformation);
  //cout<<s<<endl;
//  string testS="faceid=12345 remote=/hello out={0i 0d 0n 609B}";
  //int fid=getFaceID(testS);
  //cout<<"faceid: "<<fid<<endl;
  //string fout=getFaceOut(testS);
  //cout<<"faceout: "<<fout<<endl;
  //int testI=2778;
  //string ts=int2string(testI);
  //cout<<ts<<endl;

  //faceInfoMap.insert({110577,"1503B"});

  //while(true){
    faceInfoMap=findAndKillZombieFaces();
    sleep(60*5);
  //}

  //map<int,string>::iterator it;
  //for(it=faceInfoMap.begin();it!=faceInfoMap.end();it++){
    //cout<<it->first<<" || "<<it->second<<endl;
  //}
  return 0;	
}

// 找到并清除僵尸Face，并返回一个新的Face映射表（FaceID、FaceOut）
map<int,string> findAndKillZombieFaces(){
  string linux_command="nfdc face";
  map<int,string> newFaceInfoMap;
  // 打开文件句柄
  FILE *fp;
  if((fp=popen(linux_command.c_str(),"r"))==NULL){
    return newFaceInfoMap;
  }
  // 读取每一行：单个Face的信息
  char buf[MAXSIZE];
  while(fgets(buf,MAXSIZE,fp)!=NULL){
    //cout<<"test: "<<string(buf)<<endl;
    //sstm<<string(buf);
    // 解析该Face信息，放入map
    if(string(buf).find("faceid")==0){
      int faceid=getFaceID(string(buf));
      string faceout=getFaceOut(string(buf));
      newFaceInfoMap.insert({faceid,faceout});
      cout<<"faceid: "<<faceid<<" ; "<<"faceout: "<<faceout<<endl;
      // 杀掉out不变的face 
      if(faceInfoMap.find(faceid)!=faceInfoMap.end()&&
           (faceInfoMap.find(faceid)->second)==faceout){ 
        string killcmd="nfdc face destroy "+int2string(faceid);
        cout<<"kill face "+int2string(faceid)+" result: "<<execLinuxCommand(killcmd)<<endl;
      }   
    }	
  }
  // 关闭文件句柄
  if(pclose(fp)==-1){
    return newFaceInfoMap;
  }
  return newFaceInfoMap;
}

// 从face信息中切割出faceID
int getFaceID(string faceInfoString){
  int beginIndex=faceInfoString.find("faceid=")+7;
  faceInfoString=faceInfoString.substr(beginIndex,faceInfoString.length());
  int endIndex=faceInfoString.find(" ");
  string idString=faceInfoString.substr(0,endIndex);
  return atoi(idString.c_str());
}

// 从face信息中切割出out信息：face发出的总数据量
string getFaceOut(string faceInfoString){
  int beginIndex=faceInfoString.find("out={")+5;
  faceInfoString=faceInfoString.substr(beginIndex,faceInfoString.length());
  beginIndex=faceInfoString.find("n ")+2;
  faceInfoString=faceInfoString.substr(beginIndex,faceInfoString.length());
  int endIndex=faceInfoString.find("}");
  string outString=faceInfoString.substr(0,endIndex);
  return outString;  
}

// int转string
string int2string(int number){
  stringstream sstm;
  sstm<<number;
  return sstm.str();
}

// 执行shell命令，并返回执行结果
string execLinuxCommand(const string& linux_command){
  // 打开文件句柄
  FILE *fp;
  if((fp=popen(linux_command.c_str(),"r"))==NULL){
    return "error: popen error";
  }
  // 读取响应
  char buf[MAXSIZE];
  stringstream sstm;
  while(fgets(buf,MAXSIZE,fp)!=NULL){
    // cout<<"test: "<<string(buf)<<endl;
    sstm<<string(buf);
  }
  // 关闭文件句柄
  if(pclose(fp)==-1){
    return "error: pclose error";
  }
  return sstm.str();
}
